#include<iostream>
#include<queue>
using namespace std;
class TreeNode {
public:
	char Data;
	int H;
	TreeNode* left;
	TreeNode* right;
	TreeNode(char ch='-') {
		Data = ch;
		left = right = NULL;
	}
};
class Tree {
public:
	TreeNode* tmp;
	Tree() {
		tmp = NULL;
	}
	TreeNode* CreatTree(string str) {
		TreeNode* p1 = new TreeNode;
		p1->Data = str[0];
		p1->H = 0;
		TreeNode* p2 = new TreeNode;
		p2->Data = str[1];
		p2->H = 1;
		TreeNode* p3 = new TreeNode;
		p3->Data = str[2];
		p3->H = 1;
		p1->left = p2;
		p1->right = p3;
		return p1;
	}
	TreeNode* cmp(TreeNode* p, string str, int* m) {
		if (p == NULL) {
			return NULL;
		}
		if (p->Data == str[0]) {
			if (str[1] != '-') {
				TreeNode* cur1 = new TreeNode;
				cur1->Data = str[1];
				cur1->H = p->H + 1;
				p->left = cur1;
			}
			if (str[2] != '-') {
				TreeNode* cur2 = new TreeNode;
				cur2->Data = str[2];
				cur2->H = p->H + 1;
				p->right = cur2;
			}
			*m = 1;
		}
		else {
			p->left = cmp(p->left, str, m);
			p->right = cmp(p->right, str, m);
		}
		return p;
	}
	void print(TreeNode* p) {
		if (p == NULL) {
			return;
		}
		cout << p->Data << ' ';
		print(p->left);
		print(p->right);
	}
	bool find(TreeNode* p, char ch) {
		if (p == NULL) {
			return false;
		}
		if (p->Data == ch) {
			return true;
		}
		bool a = find(p->left, ch);
		bool b = find(p->right, ch);
		return a || b;
	}
	TreeNode* index(TreeNode* p, char ch) {
		if (p == NULL) {
			return NULL;
		}
		if (p->Data == ch) {
			return p;
		}
		TreeNode* p1 = index(p->left,ch);
		TreeNode* p2 = index(p->right,ch);
		if (p1 != NULL) {
			return p1;
		}
		else {
			return p2;
		}
	}
	void show(TreeNode* p, char ch1, char ch2) {
		queue<TreeNode*> q;
		q.push(p);
		int n1 = -1, n2 = -1;
		while (!q.empty()) {
			TreeNode* tmp = q.front();
			if (tmp->Data == ch1) {
				n1 = tmp->H;
			}
			if (tmp->Data == ch2) {
				n2 = tmp->H;
			}
			if (tmp->left != NULL) {
				q.push(tmp->left);
			}
			if (tmp->right != NULL) {
				q.push(tmp->right);
			}
			if (n1 != -1 && n2 != -1) {
				break;
			}
			q.pop();
		}
		int m = n1 - n2;
		if (m < 0) {
			if (m == -1) {
				cout << "child" << endl;
			}
			else if (m == -2) {
				cout << "grandchild" << endl;
			}
			else {
				while (m < -2) {
					cout << "great-";
					m++;
				}
				cout << "grandchild" << endl;
			}
		}
		if (m > 0) {
			if (m == 1) {
				cout << "parent" << endl;
			}
			else if (m == 2) {
				cout << "grandparent" << endl;
			}
			else {
				while (m > 2) {
					cout << "great-";
					m--;
				}
				cout << "grandparent" << endl;
			}
		}
	}
};
int main() {
	int n, m;
	cin >> n >> m;
	while (n != 0 && m != 0) {
		int N = 0;
		Tree* tmp = new Tree[n];
		string* ptr = new string[n];
		for (int i = 0; i < n; i++) {
			cin >> ptr[i];
		}
		Tree t;
		t.tmp = t.CreatTree(ptr[0]);
		tmp[N] = t;
		N++;
		int k = 0;
		for (int i = 1; i < n; i++) {
			k = 0;
			t.cmp(t.tmp, ptr[i], &k);
			if (k == 0) {
				Tree* p = new Tree;
				p->tmp = p->CreatTree(ptr[i]);
				tmp[N] = *p;
				N++;
			}
		}
		for (int i = 0; i < m; i++) {
			char ch1, ch2;
			cin >> ch1 >> ch2;
			int y = 0;
			for (int j = 0; j < N; j++) {
				if (tmp[j].find(tmp[j].tmp, ch1) && tmp[j].find(tmp[j].tmp, ch2)) {
					//cout << "wudi" << endl;
					if (ch1 < ch2) {
						TreeNode* q = tmp[j].index(tmp[j].tmp, ch1);
						if (tmp[j].find(q, ch2)) {
							tmp[j].show(tmp[j].tmp, ch1, ch2);
							y = 1;
							break;
						}
					}
					else {
						TreeNode* q = tmp[j].index(tmp[j].tmp, ch2);
						if (tmp[j].find(q, ch1)) {
							tmp[j].show(tmp[j].tmp, ch1, ch2);
							y = 1;
							break;
						}
					}
				}
			}
			if (y == 0) {
				cout << '-' << endl;
			}
		}
		delete[]tmp;
		delete[]ptr;
		cin >> n >> m;
	}
	return 0;
}